    #pragma once
#include <vector>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>

class ThreadPool {
public:
    /**
     * @brief Creates a new thread pool with the specified number of threads.
     *
     * @param num_threads The number of threads to create in the pool.
     */
    ThreadPool(size_t num_threads);

    /**
     * @brief Destructor for the ThreadPool class.
     */
    ~ThreadPool();

    /**
     * @brief Enqueues a new task to be executed by one of the threads in the pool.
     *
     * @param task A function object that represents the task to be executed.
     */
    void enqueue(std::function<void()> task);

private:
    /**
     * @brief The worker thread function that continuously dequeues and executes tasks from the queue.
     */
    void worker();

private:
    std::vector<std::thread> workers; /*!< Vector of worker threads. */
    std::queue<std::function<void()>> tasks; /*!< Queue of tasks to be executed. */

    std::mutex queue_mutex; /*!< Mutex for thread-safe access to the task queue */
    std::condition_variable condition; /*!< Condition variable to signal workers to wake up and execute tasks. */
    std::atomic<bool> stop; /*!< Atomic boolean flag indicating whether the pool should stop accepting new tasks. */
};
